<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务，帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2024 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件，不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);

namespace app\store\service\order;

use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use app\store\model\{order\Export2 as ExportModel, OrderAddress as OrderAddressModel};

use app\store\model\jia\Dengji as OrderModel;
use app\common\library\helper;
use app\common\service\BaseService;
use app\common\service\Goods as GoodsService;
use app\common\enum\order\{
    PayStatus as PayStatusEnum,
    OrderSource as OrderSourceEnum,
    OrderStatus as OrderStatusEnum,
    DeliveryType as DeliveryTypeEnum,
    ReceiptStatus as ReceiptStatusEnum,
    DeliveryStatus as DeliveryStatusEnum,
    export\ExportStatus as ExportStatusEnum
};
use app\common\enum\payment\Method as PaymentMethodEnum;
use cores\exception\BaseException;

/**
 * 服务层：订单导出Excel
 * Class Export
 * @package app\store\service\order
 */
class Export2 extends BaseService
{
    // 表格文件标题名称
    private string $title = '患者基本情況导出';

    /**
     * 执行订单导出excel
     * @param array $param
     * @return bool
     * @throws BaseException
     */
    public function exportOrder(array $param): bool
    {
        // 根据条件查询订单列表
        $orderList = $this->getOrderList($param);


         $param['columns'] =['build','real_name','mobile','start_date','service_type','clerk','buyer_remark','family_name','one','pay_status','two','three','four','five','six','sevene','eight','nine','ten','eleven','twelve','thirteen'];
       
       $columns = $this->getColumns($param['columns']);

        // 格式化生成表格数据
        $excelList = $this->getExcelList($orderList, $param['columns']);
   
        // 输出并写入到excel文件
        $filePath = $this->outputExcel($columns, $excelList);
        // 新增订单导出记录
        $this->record($param, $filePath);
        return true;
    }

    /**
     * 根据条件查询订单列表
     * @param array $param
     * @return mixed
     * @throws BaseException
     */
    private function getOrderList(array $param)
    {
        // 根据条件查询订单列表
        $orderList = (new OrderModel)->getList($param);

        if (empty($orderList)) {
            throwError('很抱歉，没有查询到数据');
        }
        return $orderList;
    }

    /**
     * 输出并写入到excel文件
     * @param array $columns 列名
     * @param array $excelList 表格内容
     * @return string
     * @throws BaseException
     */
    private function outputExcel(array $columns, array $excelList): string
    {
        // 生成工作表
        $spreadsheet = new Spreadsheet();
        $sheet = $spreadsheet->getActiveSheet()->setTitle($this->title);
        // 列宽
        $sheet->getDefaultColumnDimension()->setWidth(24);
        // 默认行高
        $sheet->getDefaultRowDimension()->setRowHeight(20);
        // 字体加粗(第一行)
        $sheet->getStyle('1')->getFont()->setBold(true);
        // 写入标题数据
        foreach ($columns as $key => $val) {
            $sheet->setCellValueByColumnAndRow($key + 1, 1, $val);
        }
        // 写入内容数据
        foreach ($excelList as $key => $item) {
            $row = $key + 2;
            foreach (array_values($item) as $k => $val) {
                $sheet->setCellValueByColumnAndRow($k + 1, $row, $val);
            }
        }
        // 生成文件路径
        $fileName = 'dnegji-' . time() . '.xlsx';
        // 获取导出的文件夹路径
        $filePath = $this->getExportPath();
        // 保存到文件
        try {
            $writer = new Xlsx($spreadsheet);
            $writer->save(public_path() . $filePath . $fileName);
        } catch (\PhpOffice\PhpSpreadsheet\Writer\Exception $e) {
            throwError($e->getMessage());
        }
        return $filePath . $fileName;
    }

    /**
     * 获取导出的文件夹路径
     * @return string
     */
    private function getExportPath(): string
    {
        $filePath = 'downloads/' . $this->getStoreId() . '/';
        !is_dir($filePath) && mkdir($filePath, 0755, true);
        return $filePath;
    }

    /**
     * 写入订单导出记录
     * @param array $param
     * @param string $filePath
     * @return void
     */
    private function record(array $param, string $filePath): void
    {
        // 生成记录数据
        $data = [
            'file_path' => $filePath,
            'status' => ExportStatusEnum::COMPLETED,
            'store_id' => $this->getStoreId(),
        ];
        // 起止时间
        if (!empty($param['betweenTime'])) {
            $times = between_time($param['betweenTime']);
            $data['start_time'] = $times['start_time'];
            $data['end_time'] = $times['end_time'];
        }
        // 新增记录
        $model = new ExportModel;
        $model->add($data);
    }

    /**
     * 获取导出的记录列名集
     * @param array $onlyFields
     * @return array
     */
    private function getColumns(array $onlyFields): array
    {
        return array_values(helper::pick($this->dictionary(), $onlyFields));
    }

    /**
     * 订单记录字典
     * @return string[]
     */
    private function dictionary(): array
    {
        return [
            'build' => '楼栋、楼层、科室、床号',
            'real_name' => '病患姓名',
            'mobile' => '电话',
            'start_date' => '开始服务时间',
            'service_type' => '陪护模式',
            'clerk' => '护理员姓名',
            'family_name' => '家属姓名',
            'one' => '能否自理',
            'two' => '精神状况',
            'three' => '神志意识',
            'four' => '手术情况',
            'five' => '情绪近况',
            'six' => '沟通情况',
            'seven' => '走动情况',
            'eight' => '饮食情况',
            'nine' => '四肢情况',
            'ten' => '皮肤情况',
            'eleven' => '大小便情况',
            'twelve' => '其他补充说明',
            'thirteen' => '入院原因',

        ];
    }

    /**
     * 格式化生成表格数据
     * @param array $orderList
     * @param array $onlyFields
     * @return array
     */
    private function getExcelList(array $orderList, array $onlyFields): array
    {
        // 获取订单表格数据
        $excelList = $this->getOrderDataForExcel($orderList);
        // 仅输出用户设置的字段
        $data = [];
        foreach ($excelList as $item) {
            $data[] = helper::pick($item, $onlyFields);
        }
        return $data;
    }

    /**
     * 获取订单列表数据(用于生成Excel)
     * @param $orderList
     * @return array
     */
    private function getOrderDataForExcel($orderList): array
    {
 
     

        // 表格内容
        $dataArray = [];
        foreach ($orderList as $order) {
            $content=json_decode($order['content'],true);
            $dataArray[] = [
                'build' => $this->filterGoodsInfo($order),
                'real_name' => $this->filterValue($order['order']['real_name']),
                'buyer_remark' => $this->filterValue($order['order']['buyer_remark']),
                'mobile' => $this->filterValue($order['order']['mobile']),
                'start_date' => $this->filterValue($order['order']['start_date']),
                'service_type' => $this->filterValue($order['order']['goods'][0]['goods_name']),
                'clerk' => $this->filterValue($order['order']['extractClerk']?$order['order']['extractClerk']['real_name']:''),
                'family_name' => $this->filterValue(isset($content[12])?$content[12]:''),
                'one' => $this->filterValue($content[0]),
                'two' =>$this->filterValue($content[1]),
                'three' =>$this->filterValue($content[2]),
                'four' =>$this->filterValue($content[3]),
                'five' =>$this->filterValue($content[4]),
                'six' =>$this->filterValue($content[5]),
                'seven' =>$this->filterValue($content[6]),
                'eight' =>$this->filterValue($content[7]),
                'nine' =>$this->filterValue(isset($content[8])?$content[8]:''),
                'ten' =>$this->filterValue(isset($content[9])?$content[9]:''),
                'eleven' =>$this->filterValue(isset($content[10])?$content[10]:''),
                'twelve' =>$this->filterValue(isset($content[11])?$content[11]:''),
                'thirteen' =>$this->filterValue(isset($content[13])?$content[13]:''),
                
            ];
        }

        return $dataArray;
    }

    /**
     * 格式化支付方式
     * @param string $payMethod
     * @return string
     */
    private function filterPayMethod(string $payMethod): string
    {
        $enum = PaymentMethodEnum::data();
        return isset($enum[$payMethod]) ? $enum[$payMethod]['name'] : '';
    }

    /**
     * 格式化商品信息
     * @param $order
     * @return string
     */
    private function filterGoodsInfo($order): string
    {
        $content = '';
         $content .= "{$order['order']['build']['name']}{$order['order']['floor']}\n";
            $content .= " {$order['order']['room']}{$order['order']['bed_no']}\n";
        return $content;
    }

    /**
     * 表格值过滤
     * @param $value
     * @return string
     */
    private function filterValue($value): string
    {
        return "\t{$value}\t";
    }
}